package com.example.demo.modules.hutool.test;

import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.log.StaticLog;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.underscore.lodash.U;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static com.example.demo.common.util.Utils.*;

public class test {
    final static String database = "databsesui";
    final static String host = "localhost";
    final static String DB_URL = strFormat("jdbc:mysql://{}:3306/{}?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", host, database);
    final static String USER = "root";
    final static String PASS = "12liumingtai";
    final static String qudong = "com.mysql.jdbc.Driver";


    public static ArrayList getTableFieldsArray(String tableName) throws JsonProcessingException, ClassNotFoundException, SQLException {
        String sql = strFormat("select COLUMN_NAME  from information_schema.COLUMNS where table_name = '{}' and table_schema = '{}';", tableName, database);
        ArrayList list = new ArrayList<String>();
        ResultSet resultSet = executeQuery(sql);
        while (resultSet.next()) {
            String key = resultSet.getString("column_name");
            if (isNotNil(key)) {
                list.add(resultSet.getString("column_name"));
            }
        }
        StaticLog.info("list========>{}   ", list);
        return list;
    }

    public static Connection getConnect() throws JsonProcessingException, ClassNotFoundException, SQLException {
        Class.forName(qudong);
        Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
        return con;
    }

    public static ResultSet executeQuery(String str) throws JsonProcessingException, ClassNotFoundException, SQLException {
        Statement statement = getConnect().createStatement();
        ResultSet resultSet = statement.executeQuery(str);
        return resultSet;
    }

    public static ArrayList query(String sql, String tableName) throws JsonProcessingException, ClassNotFoundException, SQLException {
        ResultSet resultSet = executeQuery(sql);
        ArrayList tableFieldsArray = getTableFieldsArray(tableName);
        ArrayList list = new ArrayList<String>();
        int index = 0;
        while (resultSet.next()) {
            HashMap<String, Object> hashmap1 = new HashMap<>();
            U.of(tableFieldsArray).map(key -> {
                try {
                    String value = resultSet.getString(toStr(key));
                    hashmap1.put(toStr(key), value);
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
                return key;
            });
            list.add(hashmap1);

        }

        return list;
    }


    static ArrayList page(String tableName, int pageNum, int pageSize, HashMap<String, Object> params) throws ClassNotFoundException, SQLException, JsonProcessingException {
      /*  U.map(params.entrySet(),
                new Function<Map.Entry<String, String>, String>() {
                    @Override
                    public String apply(Map.Entry<String, String> stringStringEntry) {

                        return stringStringEntry.getKey();
                    }
                });*/
        StrBuilder whereSql = createStrBuilder();
        if (isNotNil(params)) {
            myObjectMap(params, (key, value) -> {
                whereSql.append(createStr("{} = {} and ", "", value));
            });

        }
        StrBuilder whereStr = null;
        if (isNotNil(whereSql.toString())) {
            //去掉最后的and
            whereStr = createStrBuilder(" where ").append(
                    StrUtil.sub(whereSql.toString(), 0, whereSql.toString().length()));
        }
        StrBuilder append = createStrBuilder(whereSql.toString()).append(createStr(" limit {},{}", pageNum, pageSize));


        String sql = createStr("select * from {}  {} ;", tableName, append.toString());
        return query(sql, tableName);
    }


    public static void main(String[] args) throws JsonProcessingException, ClassNotFoundException, SQLException {
       /* HashMap<String, Object> hashmap1 = new HashMap<>();
        hashmap1.put("love", 1);
        ArrayList resultList = page("bind_table", 0, 10, hashmap1);
        StaticLog.info("resultList========>{}   ", resultList);
        if (isNotNil(resultList)) {
            U.of(resultList).forEach(item -> {
                StaticLog.info("item========>{}   ", item);
            });
        }*/
        class ParamTypeItem{
            Type type;
            Type[]  typeArguments;

            public Type getType() {
                return type;
            }

            public void setType(Type type) {
                this.type = type;
            }

            public Type[] getTypeArguments() {
                return typeArguments;
            }

            public void setTypeArguments(Type[] typeArguments) {
                this.typeArguments = typeArguments;
            }
        }
        class MethodItem{
            List<ParamTypeItem> paramTypes;
            Type returnType;

            public List<ParamTypeItem> getParamTypes() {
                return paramTypes;
            }

            public void setParamTypes(List<ParamTypeItem> paramTypes) {
                this.paramTypes = paramTypes;
            }

            public Type getReturnType() {
                return returnType;
            }

            public void setReturnType(Type returnType) {
                this.returnType = returnType;
            }
        }
        HashMap<String, MethodItem> utilsMethodsMap = new HashMap<>();
        Method[] classMethods = getClassMethods(Class.forName("com.example.demo.common.util.Utils"));
        U.of(classMethods).forEach(method -> {
            MethodItem methodItem = new MethodItem();
//            StaticLog.info("method========>{}   ", method);
            Type[] paramTypes = TypeUtil.getParamTypes(method);
            Type returnType = TypeUtil.getReturnType(method);
            if(null!=returnType){
                methodItem.setReturnType(returnType);
                List<ParamTypeItem> paramTypeItems=new ArrayList<>();
                U.of(paramTypes).forEach(paramType -> {
                    ParamTypeItem paramTypeItem = new ParamTypeItem();
                    paramTypeItem.setType(paramType);
                    paramTypeItem.setTypeArguments(TypeUtil.getTypeArguments(paramType));
                    paramTypeItems.add(paramTypeItem);
                });
                methodItem.setParamTypes(paramTypeItems);
                utilsMethodsMap.put(method.getName(), methodItem);
            }

        });

        StaticLog.info("classMethods111========>{}", tojsonStr(utilsMethodsMap));
    }

    private static Method[] getClassMethods(Class<?> clazz) {
        return ReflectUtil.getMethods(clazz);
    }
}
